#pragma once

/* 负责将 locks转换为apds 接口 */
#include <ddblk/apds/apds_def.h>
#include <ddblk/apds/apds_hdef.h>
#include <ddblk/apds/apds_tinfo.h>

#include <ddblk/locks.h>

#define LOCKS2APDS(lockinst, name, get_fut, ret_fut)	\
typedef lockinst##lock_t name##_t;\
typedef lockinst##node_t name##node_t;\
SIN apds_t* name##_init (void *ptr, size_t size){ return (apds_t *)lockinst##_init(ptr, size); }\
SIN void* name##_destruct (apds_t *l){ return lockinst##_destruct((lock_t *)l); }	\
SAI apdsfuture_t* name##_fetch (apds_t *l, apdsfunc_t *pfunc, apdsarg_t *args){		\
	PARAM_USED(l);									\
	apdsfuture_t *fut = get_fut();							\
	apds_movargs(&fut->args, args);							\
	fut->func = pfunc;								\
	return fut; }									\
SAI apdsret_t name##_wait (apds_t *l, apdsfuture_t *f){					\
	locktoken_t token = NULL;							\
	lockinst##_lock((lock_t *)l, &token);						\
	apdsret_t ret = apds_sync_single(f->func, &f->args);				\
	lockinst##_unlock((lock_t *)l, token);						\
	ret_fut(f);									\
	return ret; }									\
SAI apdsret_t name##_sync (apds_t *l, apdsfunc_t *pfunc, apdsarg_t *args){		\
	locktoken_t token = NULL;							\
	lockinst##_lock((lock_t *)l, &token);						\
	apdsret_t ret = apds_sync_single(pfunc, args);					\
	lockinst##_unlock((lock_t *)l, token);						\
	return ret;									\
}\
NEW_OUFUN(apds, name, name##_init, name##_destruct, name##_fetch, name##_wait, name##_sync)
